﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.Rendering;

public class GlowPost : MonoBehaviour
{
    /// <summary>
    /// 采样次数，消耗GPU性能
    /// </summary>
    [Range(2, 5)]
    public int samplingIteration = 3;
    [Range(0, 2)]
    public float glowStrength = 1;
    [Range(1, 5)]
    public float glowWidth = 3;
    [Tooltip("是否使用unity的depth获取方式")]
    public bool useUnityDepthMode = true;
    /// <summary>
    /// 作为光辉的renderer
    /// </summary>
    [HideInInspector]
    public List<GlowRenderer> renderers;
    public Shader postRenderColor, blur, add;
    Material blurMat,
        addMat;
    CommandBuffer commandBuffer;
    RenderTexture renderTexture;
    Camera _cam;
    Material colorMat;
    // Start is called before the first frame update
    void Start()
    {
        _cam = GetComponent<Camera>();
        if(useUnityDepthMode)
            _cam.depthTextureMode = DepthTextureMode.Depth;
        blurMat = new Material(blur);
        addMat = new Material(add);
        colorMat = new Material(postRenderColor);
    }

    // Update is called once per frame
    void Update()
    {
        SetProperties();
    }

    void SetProperties()
    {

        blurMat.SetInt("_SamplingIteration", samplingIteration);
        blurMat.SetFloat("_Width", glowWidth);
        blurMat.SetFloat("_Strength", glowStrength);
    }

    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {

        int Width = _cam.pixelWidth;
        int Height = _cam.pixelHeight;

        commandBuffer = new CommandBuffer();
        //创建rt使用该方法，否则无法释放资源,https://docs.unity3d.com/540/Documentation/ScriptReference/RenderTexture.GetTemporary.html
        renderTexture = RenderTexture.GetTemporary(Width, Height, 24, RenderTextureFormat.ARGB1555, RenderTextureReadWrite.Default);

        commandBuffer.SetRenderTarget(renderTexture);
        commandBuffer.ClearRenderTarget(true, true, Color.clear);

        foreach (var item in renderers)
        {
            if (!item.enabled)
                continue;
            colorMat.SetFloat("_Scale", item.scale);
            colorMat.SetColor("_Color", item.color);
            commandBuffer.DrawRenderer(item.meshRenderer, colorMat, 0, 0);
        }
        Graphics.ExecuteCommandBuffer(commandBuffer);
        RenderTexture temp1 = RenderTexture.GetTemporary(renderTexture.width, renderTexture.height, 24, renderTexture.format, RenderTextureReadWrite.Default);



        for (int i = 0; i < samplingIteration; i++)
        {
            blurMat.SetVector("_offsets", new Vector4(0, glowWidth, 0, 0));
            Graphics.Blit(renderTexture, temp1, blurMat);

            blurMat.SetVector("_offsets", new Vector4(glowWidth, 0, 0, 0));
            Graphics.Blit(temp1, renderTexture, blurMat);
        }
        addMat.SetTexture("_AddTex", renderTexture);
        Graphics.Blit(source, destination, addMat);


        commandBuffer.Clear();
        commandBuffer.Dispose();
        //释放RT使用该方法，否则无法释放资源
        RenderTexture.ReleaseTemporary(renderTexture);
        renderTexture = null;

        RenderTexture.ReleaseTemporary(temp1);
        temp1 = null;
    }
}
